/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.hiddendanger.controller;

import com.google.gson.Gson;
import com.koron.common.Excel;
import com.koron.common.StaffAttribute;
import com.koron.common.bean.DeptBean;
import com.koron.common.bean.StaffBean;
import com.koron.common.domain.DataBean;
import com.koron.common.permission.SPIAccountAnno;
import com.koron.common.web.Util;
import com.koron.hiddendanger.domain.PerformancePlan;
import com.koron.hiddendanger.service.api.PerformancePlanService;
import com.koron.hiddendanger.uitls.BusinessCode;
import com.koron.system.annotation.Log;
import com.koron.system.discrete.BusinessManipulation;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.swan.bean.MessageBean;
import springfox.documentation.annotations.ApiIgnore;

import java.io.File;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "performancePlan", description = "检查计划相关接口")
@RestController
@RequestMapping("/performancePlan")
public class PerformancePlanController {

    @Autowired
    private PerformancePlanService planService;
    private final static Logger logger = LoggerFactory.getLogger(PerformancePlanController.class);

    @Autowired
    private Util util;

    @ApiOperation("提交检查计划接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检查计划id,新增不传，修改必传", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "检查计划名称", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "description", value = "计划描述", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "corpCode", value = "检查范围——水司code", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "gridCode", value = "检查范围——网格code", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "gridName", value = "检查范围——网格名称", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "repeatType", value = "周期类型,0:每周,1:每月,2:每季度,3:每半年,4:每年,5:单次", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "beginTime", value = "开始时间，计划开始时间", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "endTime", value = "截止时间,计划截止时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "planApprover", value = "计划审批人code和所在单位code, 格式用下划线分隔", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "planApproverName", value = "计划审批人名称和所在单位名称, 格式用下划线分隔", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "executors", value = "检查执行人，可以选择多个执行人员，存code和所在单位code,存储格式为json格式{'codes':[staffCode_departmentCode,staffCode_departmentCode]}", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "executorsName", value = "检查执行人，可以选择多个执行人员，存code和所在单位code,存储格式为json格式{'codes':[staffCode_departmentCode,staffCode_departmentCode]}", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "innerWorkers", value = "内部检查人员code和所在单位code,,存储格式为json格式{'codes':[staffName_departmentName,...]}", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "innerWorkersName", value = "内部检查人员名称和所在单位名称,,存储格式为json格式{'codes':[staffName_departmentName,...]}", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "outterWorkers", value = "外部检查人员和所在单位,可以输入多个检查人员，不同检查人员之间用,分开，格式：名称_部门，名称_部门", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "identifier", value = "验证人code", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "identifierName", value = "验证人名称", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "manager", value = "负责人code,最终负责人", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "managerName", value = "负责人名称,最终负责人", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "checkLevel", value = "检查层级", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "checkLevelName", value = "检查层级名称", required = true, dataType = "String", paramType = "query"),
    })
    @RequestMapping(value = "/save.htm", method = RequestMethod.POST)
    @Log(title = "提交检查计划",businessModule = "检查计划" ,  businessManipulation = BusinessManipulation.DELETE)
    public MessageBean<Integer> save(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @ApiIgnore PerformancePlan plan) {
        if (null == user) {
            MessageBean<Integer> msg = new MessageBean<>();
            msg.setCode(BusinessCode.NOT_LONGIN.getCode());
            msg.setDescription(BusinessCode.NOT_LONGIN.getDescription());
            return msg;
        }
        plan.setUpdateTime(new Date());
        plan.setUpdateUser(user.getName());
        //设置执行人和内部检查人员格式
        if (StringUtils.isNotEmpty(plan.getExecutors())) {
            String[] codeArray = plan.getExecutors().split("[,，]");
            List<String> codes = Arrays.asList(codeArray).stream().map(String::trim).collect(Collectors.toList());
            plan.setExecutors(new Gson().toJson(codes));
        }
        if (StringUtils.isNotEmpty(plan.getInnerWorkers())) {
            String[] codeArray = plan.getInnerWorkers().split("[,，]");
            List<String> codes = Arrays.asList(codeArray).stream().map(String::trim).collect(Collectors.toList());
            plan.setInnerWorkers(new Gson().toJson(codes));
        }
        if (StringUtils.isNotEmpty(plan.getExecutorsName())) {
            String[] codeArray = plan.getExecutorsName().split("[,，]");
            List<String> codes = Arrays.asList(codeArray).stream().map(String::trim).collect(Collectors.toList());
            plan.setExecutorsName(new Gson().toJson(codes));
        }
        if (StringUtils.isNotEmpty(plan.getInnerWorkersName())) {
            String[] codeArray = plan.getInnerWorkersName().split("[,，]");
            List<String> codes = Arrays.asList(codeArray).stream().map(String::trim).collect(Collectors.toList());
            plan.setInnerWorkersName(new Gson().toJson(codes));
        }
        return planService.save(user, plan);
    }


    @ApiOperation("批量提交检查计划，启动流程")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "title", value = "提交流程的标题", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "note", value = "提交流程的描述", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "approval", value = "提交选择的审批人,格式为userCode_userId", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "performancePlanIds", value = "选中检查计划的id,多个id用，分割", dataType = "String", paramType = "query")
    })
    @Log(title = "批量启动检查计划流程",businessModule = "检查计划" ,  businessManipulation = BusinessManipulation.INSERT)
    @RequestMapping(value = "/batchCommit.htm", method = RequestMethod.POST)
    public MessageBean<Integer> batchCommit(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, String corpCode, String title, String note, String approval, String performancePlanIds) {
        MessageBean<Integer> msg = new MessageBean<>();
        if (null == user) {
            msg.setCode(BusinessCode.NOT_LONGIN.getCode());
            msg.setDescription(BusinessCode.NOT_LONGIN.getDescription());
            return msg;
        }
        return planService.batchCommit(user, corpCode, title, note, approval, performancePlanIds);
    }

    @ApiOperation("删除检查计划接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检查计划id", required = true, dataType = "String", paramType = "query"),
    })

    @RequestMapping(value = "/delete.htm", method = RequestMethod.POST)
    @Log(title = "删除检查计划",businessModule = "检查计划" ,  businessManipulation = BusinessManipulation.DELETE)
    public MessageBean<Integer> delete(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam final String id) {
        if (null == user) {
            MessageBean<Integer> messageBean = new MessageBean<>();
            messageBean.setCode(BusinessCode.NOT_LONGIN.getCode());
            messageBean.setDescription(BusinessCode.NOT_LONGIN.getDescription());
            return messageBean;
        }
        return planService.dummyRemove(user, id);
    }

    @ApiOperation("根据id查询检查计划详情接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检查计划id", required = true, dataType = "String", paramType = "query"),
    })
    @RequestMapping(value = "/detalis.htm", method = RequestMethod.POST)
    public MessageBean<PerformancePlan> detalis(@RequestParam final String id) {
        return planService.queryOne(id);
    }


    @ApiOperation("获取流程业务详情数据接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "businessIds", value = "检查计划id", required = true, dataType = "String", paramType = "query"),
    })
    @RequestMapping(value = "/getBusinessData.htm", method = RequestMethod.POST)
    public MessageBean<List<PerformancePlan>> getBusinessData(@RequestParam final String businessIds) {
        return planService.getBusinessData(businessIds);
    }

    @ApiOperation("根据id暂停检查计划详情接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检查计划id", required = true, dataType = "String", paramType = "query"),
    })
    @RequestMapping(value = "/pausePlan.htm", method = RequestMethod.POST)
    @Log(title = "暂停检查计划",businessModule = "检查计划" , businessManipulation = BusinessManipulation.UPDATE)
    public MessageBean<Boolean> pausePlan(String id) {
        return planService.pausePlan(id);
    }

    @ApiOperation("根据id恢复检查计划详情接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检查计划id", required = true, dataType = "String", paramType = "query"),
    })
    @RequestMapping(value = "/resumePlan.htm", method = RequestMethod.POST)
    @Log(title = "重新启动检查计划",businessModule = "检查计划" ,  businessManipulation = BusinessManipulation.UPDATE)
    public MessageBean<Boolean> resumePlan(String id) {
        return planService.resumePlan(id);
    }

    @ApiOperation("根据指定条件检查计划列表接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "检查计划名称", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "planCreater", value = "计划制定人code和所在单位code, 格式用下划线分隔", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "corpCode", value = "检查范围——水司code", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "gridCode", value = "检查范围——水司code", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "repeatType", value = "周期类型,0:每周,1:每月,2:每季度,3:每半年,4:每年,5:单次", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "executors", value = "检查执行人，可以选择多个执行人员，存code和所在单位code,存储格式为json格式{'codes':[staffCode_departmentCode,staffCode_departmentCode]}", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "useState", value = "计划使用状态", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "当前页", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "int", paramType = "query"),
    })
    @RequestMapping(value = "/list.htm", method = RequestMethod.POST)
    public MessageBean<DataBean<PerformancePlan>> list(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, String name, String planCreater, String corpCode, String gridCode, String executors,
                                                       Integer useState, Integer repeatType, Integer page, Integer pageSize) {
        MessageBean<DataBean<PerformancePlan>> msg = new MessageBean<>();
        if (null == user) {
            msg.setCode(BusinessCode.NOT_LONGIN.getCode());
            msg.setDescription(BusinessCode.NOT_LONGIN.getDescription());
            return msg;
        }
        Integer start = null;
        if (page == null || page <= 0) {
            page = 1;
            if (pageSize == null || pageSize <= 0) {
                pageSize = 15;
            }
        }
        start = (page <= 1) ? 0 : (page - 1) * pageSize;
        msg = planService.queryByCondition(user,name, planCreater, corpCode, gridCode, executors, null, useState, repeatType, start, pageSize);
        if (null != msg.getData())
            msg.getData().setPageNo(page == null ? 1 : page);
        return msg;
    }

    @ApiOperation("检查记录--选择检查计划接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "corpCode", value = "检查范围——水司code", dataType = "String", paramType = "query"),
    })
    @RequestMapping(value = "/queryAll.htm", method = RequestMethod.POST)
    public MessageBean<List<PerformancePlan>> queryAll(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, String corpCode) {
        if (null == user) {
            MessageBean<List<PerformancePlan>> messageBean = new MessageBean<>();
            messageBean.setCode(BusinessCode.NOT_LONGIN.getCode());
            messageBean.setDescription(BusinessCode.NOT_LONGIN.getDescription());
            return messageBean;
        }
        MessageBean<List<PerformancePlan>> msg = new MessageBean<>();
        msg = planService.queryAll(corpCode, user.getCode());
        return msg;
    }

    @ApiOperation("app端查询检查计划列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userCode", value = "当前登录人的code", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "当前页", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "int", paramType = "query"),
    })
    @RequestMapping(value = "/appList.htm", method = RequestMethod.POST)
    public MessageBean<DataBean<PerformancePlan>> appList(@RequestParam final String userCode, @RequestParam Integer page, @RequestParam Integer pageSize) {
        MessageBean<DataBean<PerformancePlan>> msg = new MessageBean<>();
        List<StaffBean> staffBeanList = (List<StaffBean>) util.staff(userCode, null).getData();
        if (null == staffBeanList && staffBeanList.size() <= 0) {
            msg.setCode(BusinessCode.NOT_LONGIN.getCode());
            msg.setDescription(BusinessCode.NOT_LONGIN.getDescription());
            return msg;
        }
        StaffBean user = staffBeanList.get(0);
        List<DeptBean> deptBeanList = (List<DeptBean>) util.dept(user.getCode()).getData();
        if (deptBeanList == null || deptBeanList.size() <= 0) {
            msg.setCode(BusinessCode.NOT_LONGIN.getCode());
            msg.setDescription(BusinessCode.NOT_LONGIN.getDescription());
            return msg;
        }
        Integer start = null;
        if (page == null || page <= 0) {
            page = 1;
            if (pageSize == null || pageSize <= 0) {
                pageSize = 15;
            }
        }
        start = (page <= 1) ? 0 : (page - 1) * pageSize;
        String code = user.getCode() + "_" + deptBeanList.get(0).getCode();
        msg = planService.appList(code, start, pageSize);
        if (null != msg.getData())
            msg.getData().setPageNo(page == null ? 1 : page);
        return msg;
    }

    @ApiOperation("PC端首页安全工作的安全计划列表接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query"),
    })
    @RequestMapping(value = "/indexPerformancePlanList.htm", method = RequestMethod.POST)
    public MessageBean<DataBean<PerformancePlan>> indexPerformancePlanList(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, @RequestParam(required = false) Integer page, @RequestParam(required = false) Integer pageSize) {
        MessageBean<DataBean<PerformancePlan>> msg = new MessageBean<>();
        if (null == user) {
            msg.setCode(BusinessCode.NOT_LONGIN.getCode());
            msg.setDescription(BusinessCode.NOT_LONGIN.getDescription());
            return msg;
        }
//        List<DeptBean> deptBeanList = (List<DeptBean>) util.dept(user.getCode()).getData();
//        if (deptBeanList == null || deptBeanList.size() <= 0) {
//            msg.setCode(BusinessCode.NOT_LONGIN.getCode());
//            msg.setDescription(BusinessCode.NOT_LONGIN.getDescription());
//            return msg;
//        }
        Integer start = null;
        if (page != null) {
            if (page <= 0) {
                page = 1;
                if (pageSize == null || pageSize <= 0) {
                    pageSize = 15;
                }
            }
            start = (page <= 1) ? 0 : (page - 1) * pageSize;
        }
        String code = user.getCode() + "_" + user.getUserid();
        msg = planService.indexPerformancePlanList(code, start, pageSize);
        if (msg.getData() != null)
            msg.getData().setPageNo(page == null ? 1 : page);
        return msg;
    }


    @ApiOperation("检查计划列表导出接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "检查计划名称", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "planCreater", value = "计划制定人code和所在单位code, 格式用下划线分隔", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "corpCode", value = "检查范围——水司code", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "gridCode", value = "检查范围——水司code", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "repeatType", value = "周期类型,0:每周,1:每月,2:每季度,3:每半年,4:每年,5:单次", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "executors", value = "检查执行人，可以选择多个执行人员，存code和所在单位code,存储格式为json格式{'codes':[staffCode_departmentCode,staffCode_departmentCode]}", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "useState", value = "计划使用状态", dataType = "String", paramType = "query"),
    })
    @RequestMapping(value = "/exportList.htm", method = RequestMethod.GET)
    public HttpEntity<?> export(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user, String name, String planCreater, String corpCode, String gridCode, String executors,
                                Integer useState, Integer repeatType) {
        if (null == user) {
            return null;
        }
        List<PerformancePlan> list = planService.exportList(user, corpCode, name, planCreater, gridCode, executors, useState, repeatType);
        Map<String, Object> map = new HashMap<>();

        map.put("data", list);
        File targetFile = new File("static/excel/performancePlanList.xlsx");
        try {
            InputStream in = getClass().getClassLoader().getResourceAsStream("static/excel/performancePlanList.xlsx");
            FileUtils.copyInputStreamToFile(in, targetFile);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        return Excel.createFile("检查计划列表", targetFile, "performancePlanList.btl", map);
    }
}
